{% extends "tutorial.html" %}

{% block pagebreadcrumb %}{{ tut.title }}{% endblock %}

{% block html5badge %}
<img src="/static/images/identity/html5-badge-h-multimedia.png" width="133" height="64" alt="This article is powered by HTML5 Audio/Video" title="This article is powered by HTML5 Audio?/Video"  />
{% endblock %}

{% block iscompatible %}
return !!document.createElement("video").textTracks;
{% endblock %}

{% block head %}
<style>
video {
  max-width: 100%;
  outline: none;
}
div#eric video {
-webkit-box-reflect: below 5px -webkit-linear-gradient(top, transparent, transparent 80%, rgba(255,255,255,0.2));
-moz-box-reflect: below 5px -moz-linear-gradient(top, transparent, transparent 80%, rgba(255,255,255,0.2));
-ms-box-reflect: below 5px -moz-linear-gradient(top, transparent, transparent 80%, rgba(255,255,255,0.2));
-o-box-reflect: below 5px -moz-linear-gradient(top, transparent, transparent 80%, rgba(255,255,255,0.2));
margin: 0;
}

div#eric  {
  text-align: center;
}

div#eric > div {
margin-top: 2em;
text-align: center;
-webkit-perspective: 800;
-webkit-transform-style: preserve-3d;
-moz-perspective: 800;
-moz-transform-style: preserve-3d;
-ms-perspective: 800;
-ms-transform-style: preserve-3d;
-o-perspective: 800;
-o-transform-style: preserve-3d;
}

div#eric > div > div:last-child {
position: relative;
top: -36px;
}
div#eric > div > div {
color: black;
font-family: "Open Sans", sans-serif;
font-size: 18px;
height:  25px;
opacity: 1;
-webkit-transition: all 500ms ease-in-out;
-webkit-transform-origin: 50% 100%;
-webkit-transform: rotateX(-90deg);
-moz-transition: all 500ms ease-in-out;
-moz-transform-origin: 50% 100%;
-moz-transform: rotateX(-90deg);
-o-transition: all 500ms ease-in-out;
-o-transform-origin: 50% 100%;
-o-transform: rotateX(-90deg);
-ms-transition: all 500ms ease-in-out;
-ms-transform-origin: 50% 100%;
-ms-transform: rotateX(-90deg);
}
div#eric > div > div.on {
opacity: 1;
-webkit-transform: rotateX(0);
-moz-transform: rotateX(0);
-o-transform: rotateX(0);
-ms-transform: rotateX(0);
}
.trackNotSupported {
  display: none;
}
.trackNotSupported.show {
  display: block;
}
.warningMessage {
  color: red;
}

.talkinghead-dutton:before {
  background-image:url(/static/images/profiles/dutton.png);
  background-size: 60px 60px;
  background-position:0px 0px!important;
}
</style>
{% endblock %}

{% block onload %}
// TODO
{% endblock %}

{% block content %}

<h2 id="toc-introduction">Начало работы с элементом отслеживания HTML5</h2>

<p>Элемент отслеживания является простым стандартизированным инструментом для добавления субтитров, титров, описаний и глав экранного диктора к видео- и аудиоматериалам.</p>

<p>Отслеживание также можно использовать с другими типами хронометрированных метаданных. Исходные данные каждого элемента отслеживания представляют собой текстовый файл, составленный из ряда хронометрированных меток <code>cue</code>, которые могут содержать информацию в таких форматах, как JSON и CSV. Это очень функциональный инструмент, позволяющий создавать внешние ссылки и использовать навигацию через текстовый поиск в мультимедийных фрагментах, а также управлять моделью DOM и осуществлять другие действия, синхронизируемые с воспроизведением. </p>

<p>В настоящее время элемент отслеживания доступен для браузеров <a href="http://ie.microsoft.com/testdrive/" title="Загрузка Internet Explorer 10">Internet Explorer 10</a> и <a href="http://tools.google.com/dlpage/chromesxs" title="Загрузка Chrome Canary">Chrome 18+</a>. Браузер Firefox <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=629350" title="Отчет об ошибке при реализации элемента отслеживания в браузере Firefox">пока не поддерживается</a>. В браузере Chrome поддержку элемента отслеживания необходимо включить на странице <a href="chrome://flags" title="Страница chrome://flags">chrome://flags</a>.</p>

<p>Ниже приведен простой пример видео с элементом отслеживания. Чтобы просмотреть субтитры на английском языке, воспроизведите этот ролик.</p>

<video controls class="trackSupported">
  <source src="treeOfLife/video/developerStories-en.webm" type='video/webm; codecs="vp8, vorbis"' />
  <track src="treeOfLife/tracks/developerStories-subtitles-en.vtt" label="English subtitles" kind="subtitles" srclang="en" default />
</video>

<p class="warningMessage trackNotSupported">Для просмотра этого демонстрационного видеоролика необходим браузер с поддержкой элемента отслеживания, например <a href="http://tools.google.com/dlpage/chromesxs" title="Загрузка Google Chrome Canary">Google Chrome Canary</a>. В браузере Chrome поддержку элемента отслеживания необходимо включить на странице chrome://flags.</p>

<p>Ниже показано, как выглядит код элемента видео с субтитрами на английском и немецком языках.</p>

<pre class="prettyprint">
&lt;video src="foo.ogv"&gt;
  &lt;track kind="subtitles" label="English subtitles" src="subtitles_en.vtt" srclang="en" default&gt;&lt;/track&gt;
  &lt;track kind="subtitles" label="Deutsche Untertitel" src="subtitles_de.vtt" srclang="de"&gt;&lt;/track&gt;
&lt;/video&gt;
</pre>

<p>В этом примере в элементе видео можно выбрать язык субтитров. Следует упомянуть, что на момент написания статьи выбор языка субтитров еще не был реализован.</p>

<p>Обратите внимание на то, что элемент отслеживания невозможно использовать в URL типа <code>file://</code>. Чтобы испытать функцию отслеживания в действии, разместите файлы на веб-сервере.</p>

<p>У каждого элемента отслеживания есть атрибут <code>kind</code>, который принимает значение <code>subtitles</code>, <code>captions</code>, <code>descriptions</code>, <code>chapters</code> или <code>metadata</code>. Атрибут элемента отслеживания <code>src</code> указывает на текстовый файл, содержащий данные о хронометрированных метках отслеживания в любом формате, который распознается браузером. Chrome поддерживает формат WebVTT, который имеет описанный ниже вид.</p>

<pre class="prettyprint">
WEBVTT FILE

railroad
00:00:10.000 --> 00:00:12.500
Left uninspired by the crust of railroad earth

manuscript
00:00:13.200 --> 00:00:16.900
that touched the lead to the pages of your manuscript.
</pre>

<p>Каждый элемент файла отслеживания называется меткой. В метке указано время начала и окончания (значения разделены стрелкой), а ее текст располагается в следующей строке. Метки также могут иметь идентификаторы (в примерах выше – railroad и manuscript). Они разделены пустыми строками.</p>

<blockquote class="commentary talkinghead talkinghead-dutton">Время меток указывается в формате "часы:минуты:секунды:миллисекунды". Обратите внимание: анализ выполняется по строгим правилам. В случае необходимости числа дополняются нулями: часы, минуты и секунды должны состоять из двух цифр (00 для нулевого значения), а миллисекунды – из трех (000 для нулевого значения). На сайте <a href="http://quuz.org/webvtt/">quuz.org/webvtt</a> можно воспользоваться средством проверки WebVTT-файлов, обнаруживающим ошибки в формате времени и другие проблемы, такие как непоследовательность временных меток.</blockquote>

<p>Ниже приведен пример, показывающий, как выполняется поиск субтитров для навигации в видеофайле.</p>

<!-- subtitle search example -->

<h2 id="toc-jsoncues">Использование HTML и JSON в метках</h2>

<p>Если в файле WebVTT отсутствуют пустые строки, текст метки может охватывать несколько строк. Это значит, что в метках может использоваться формат HTML.</p>

<pre class="prettyprint">
WEBVTT FILE

multiCell
00:01:15.200 --> 00:02:18.800
&lt;p>Multi-celled organisms have different types of cells that perform specialised functions.&lt;/p>
&lt;p>Most life that can be seen with the naked eye is multi-cellular.&lt;/p>
&lt;p>These organisms are though to have evolved around 1 billion years ago with plants, animals and fungi having independent evolutionary paths.&lt;/p>
</pre>

<p>И это еще не все. В метках также можно использовать формат JSON.</p>

<pre class="prettyprint">
WEBVTT FILE

multiCell
00:01:15.200 --> 00:02:18.800
{
"title": "Multi-celled organisms",
"description": "Multi-celled organisms have different types of cells that perform specialised functions.
  Most life that can be seen with the naked eye is multi-cellular. These organisms are though to
  have evolved around 1 billion years ago with plants, animals and fungi having independent
  evolutionary paths.",
"src": "multiCell.jpg",
"href": "http://en.wikipedia.org/wiki/Multicellular"
}

insects
00:02:18.800 --> 00:03:01.600
{
"title": "Insects",
"description": "Insects are the most diverse group of animals on the planet with estimates for the total
  number of current species range from two million to 50 million. The first insects appeared around
  400 million years ago, identifiable by a hard exoskeleton, three-part body, six legs, compound eyes
  and antennae.",
"src": "insects.jpg",
"href": "http://en.wikipedia.org/wiki/Insects"
}
</pre>

<p>Возможность использовать в метках структурированные данные повышает функциональность и гибкость элемента отслеживания. Веб-приложение может считывать события метки, извлекать текст каждой из них при ее активизации, анализировать данные и использовать результаты этого анализа для синхронизации изменений модели DOM (или выполнения других задач JavaScript и CSS) с мультимедийным воспроизведением.</p>

<h2 id="toc-search">Поиск и углубленная навигация</h2>

<p>Отслеживание также может повысить эффективность аудио- и видеоматериалов за счет упрощения поиска, повышения его функциональности и точности.</p>
<p>Метки содержат текст, который можно индексировать, а также время начала, обозначающее временное "расположение" содержания в мультимедийном фрагменте. Метки могут даже содержать сведения о расположении объектов в видеокадре. В сочетании с <a href="https://www.youtube.com/watch?v=LfRRYp6mnu0" title="Видео YouTube, демонстрирующее реализацию URI прототипа мультимедийного фрагмента">URI мультимедийного фрагмента</a> отслеживание может стать эффективным механизмом поиска содержания в аудио- и видеоматериалах и перехода к нему. Например, поиск по запросу Etta James вернет результаты, содержащие непосредственные ссылки на моменты в видеофайле, где это имя упоминается в тексте метки.</a>

<p><a href="treeOfLife/index.html" title="Демонстрационный пример Tree Of Life, в котором используется отслеживание метаданных">Tree Of Life</a> – простой демонстрационный пример, в котором отслеживание метаданных используется для навигации путем поиска субтитров. Он также показывает, каким образом хронометрированные метаданные дают возможность управлять моделью DOM, синхронизированной с мультимедийным фрагментом.</p>

<h2 id="toc-cues-js">Отслеживание и метки с JavaScript</h2>

<p>У элементов аудио и видео есть свойство <code>textTracks</code>, возвращающее список <code>TextTrackList</code>, каждая позиция которого является объектом <code>TextTrack</code>, соответствующим элементу <code>&lt;track&gt;</code>:</p>

<pre class="prettyprint">
var videoElement = document.querySelector("video");
var textTracks = videoElement.textTracks; // one for each track element
var textTrack = textTracks[0]; // corresponds to the first track element
var kind = textTrack.kind // e.g. "subtitles"
var mode = textTrack.mode // 0 (TextTrack.OFF in spec, TextTrack.DISABLED in Chrome), 1 (TextTrack.HIDDEN) or 2 (TextTrack.SHOWING)
</pre>

<p>В свою очередь, у каждого значения <code>TextTrack</code> есть свойство <code>cues</code>, возвращающее список <code>TextTrackCueList</code>, каждая позиция которого представляет собой отдельную метку. К данным метки можно обращаться с помощью свойств, например <code>startTime</code>, <code>endTime</code> и <code>text</code> (последнее используется для извлечения текстового содержания метки), как показано ниже.</p>

<pre class="prettyprint">
var cues = textTrack.cues;
var cue = cues[0]; // corresponds to the first cue in a track src file
var cueId = cue.id // cue.id corresponds to the cue id set in the WebVTT file
var cueText = cue.text; // "The Web is always changing", for example (or some JSON!)
</pre>

<p>Иногда обращаться к объектам <code>TextTrack</code> удобнее с помощью элемента отслеживания <code>HTMLTrackElement</code>, как показано ниже.</p>

<pre class="prettyprint">
var trackElements = document.querySelectorAll("track");
// for each track element
for (var i = 0; i &lt; trackElements.length; i++) {
  trackElements[i].addEventListener("load", function() {
    var textTrack = this.track; // gotcha: "this" is an HTMLTrackElement, not a TextTrack object
    var isSubtitles = textTrack.kind === "subtitles"; // for example...
    // for each cue
    for (var j = 0; j &lt; textTrack.cues.length; ++j) {
      var cue = textTrack.cues[j];
      // do something
    }
}
</pre>

<p>Как демонстрирует этот пример, свойства <code>TextTrack</code> доступны через свойство элемента отслеживания <code>track</code>, а не через сам этот элемент. </p>

<p>Доступ к свойствам <code>TextTrack</code> возможен после (но не до) срабатывания события <code>load</code>.</p>

<h2 id="toc-events">Отслеживание и события метки</h2>

<p>Существует два типа событий метки:
<ul>
  <li>события входа и выхода, срабатывающие для меток;</li>
  <li>события изменения меток, срабатывающие для объектов отслеживания. </li>
</ul>
</p>

<p>В предыдущем примере детекторы событий метки были добавлены описанным ниже образом.</p>

<pre class="prettyprint">
cue.onenter = function(){
  // do something
};

cue.onexit = function(){
  // do something else
};
</pre>

<p>Обратите внимание на то, что события входа и выхода срабатывают только при входе в метку или выходе из нее во время воспроизведения. Если пользователь передвигает ползунок хронометража вручную, активизируется событие изменения метки для элемента отслеживания в новый момент времени, а события входа и выхода не срабатывают. Эту проблему можно решить путем считывания события изменения метки отслеживания с последующим извлечением активных меток. Обратите внимание: активных меток может быть несколько.</p>

<p>В приведенном ниже примере при изменении меток извлекается текущая метка и совершается попытка создать объект путем анализа ее текста.</p>

<pre class="prettyprint">
textTrack.oncuechange = function (){
  // "this" is a textTrack
  var cue = this.activeCues[0]; // assuming there is only one active cue
  var obj = JSON.parse(cue.text);
  // do something
}
</pre>

<h2 id="toc-notjustvideo">Не только для видео</h2>

<p>Не забывайте, что отслеживание можно применять как в видео-, так и в аудиоматериалах. Кроме того, для использования API элементов аудио, видео или отслеживания нет необходимости применять их в HTML-разметке. Документация по <a href="http://dev.w3.org/html5/spec/video.html#text-track-api" title="Документация по API текстового отслеживания W3C">API текстового отслеживания</a> содержит хороший пример упомянутого выше правила, демонстрируя удобный способ реализации "спрайтов" аудио.</p>

<pre class="prettyprint">
var sfx = new Audio('sfx.wav');
var track = sfx.addTextTrack('metadata'); // previously implemented as addTrack()

// Add cues for sounds we care about.
track.addCue(new TextTrackCue('dog bark', 12.783, 13.612, '', '', '', true));
track.addCue(new TextTrackCue('kitten mew', 13.612, 15.091, '', '', '', true));

function playSound(id) {
  sfx.currentTime = track.getCueById(id).startTime;
  sfx.play();
}

playSound('dog bark');
playSound('kitten mew');
</pre>

<p>Метод <code>addTextTrack</code> принимает три параметра: <code>kind</code> (например, "метаданные", как показано выше), <code>label</code> (например, Sous-titres français) и <code>language</code> (например, fr).</p>

<p>В примере выше также используется команда <code>addCue</code>, извлекающая объект <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttrackcue" title="Документация по WHATWG TextTrackCue"><code>TextTrackCue</code></a>, конструктор которого принимает аргументы <code>id</code> (например, "лай собаки"), <code>startTime</code>, <code>endTime</code>, <code>text</code> (текст метки), аргумент <a href="http://dev.w3.org/html5/webvtt/#webvtt-cue-settings" title="Документация по настройкам меток WebVTT"><code>параметров метки webVTT</code></a> (для определения расположения, размера и выравнивания), а также логическую пометку <code>pauseOnExit</code> (например, для паузы в воспроизведении после заданного в учебном видео вопроса).</p>

<p>Обратите внимание на то, что свойства <code>startTime</code> и <code>endTime</code> используют плавающие значения точек в секундах, а не в формате "часы:минуты:секунды:миллисекунды", применяемом в WebVTT.</p>

<p>Кроме того, метку можно удалить с помощью команды <code>removeCue()</code>, которая принимает ее в качестве аргумента, как показано в примере ниже.</p>

<pre class="prettyprint">
var videoElement = document.querySelector("video");
var track = videoElement.textTracks[0];
var activeCue = track.activeCues[0];
track.removeCue(activeCue);
</pre>

<p>Выполняя эту команду, можно заметить, что представленная метка удаляется после вызова кода.</p>

<p>У элементов отслеживания есть атрибут <code>mode</code>, принимающий значения 0 (<code>TextTrack.OFF</code> в спецификациях, <code>TextTrack.DISABLED</code> в браузере Chrome), 1 (<code>TextTrack.HIDDEN</code>) и 2 (<code>TextTrack.SHOWING</code>). Это удобно, если необходимо использовать события отслеживания при выключенной обработке по умолчанию. В приведенном ниже видео показан пример использования атрибута (видео создано <a href="http://html5-demos.appspot.com/static/whats-new-with-html5-media/template/index.html#3" title="Демонстрационная презентация по HTML5 Эрика Бидельмана">Эриком Бидельманом (Eric Bidelman)</a>).</p>

<div id="eric">
  <video width="400" controls>
    <source src="treeOfLife/video/developerStories-en.webm" type='video/webm; codecs="vp8, vorbis"'>
    <track label="English subtitles" kind="subtitles" srclang="en" src="treeOfLife/tracks/developerStories-subtitles-en.vtt" default>
  </video>
  <div><div>проверка1</div><div>asdf2</div></div>
</div>

<script>
(function(){

var video = document.querySelector('div#eric video');
var span1 = document.querySelector('div#eric > div :first-child');
var span2 = document.querySelector('div#eric > div :last-of-type');

if (!video.textTracks) return;

var track = video.textTracks[0];
track.mode = TextTrack.HIDDEN;

var idx = 0;

track.oncuechange = function(e) {

  var cue = this.activeCues[0];
  if (cue) {
    if (idx == 0) {
      span2.className = '';
      span1.classList.remove('on');
      span1.innerHTML = '';
      span1.appendChild(cue.getCueAsHTML());
      span1.classList.add('on');
    } else {
      span1.className = '';
      span2.classList.remove('on');
      span2.innerHTML = '';
      span2.appendChild(cue.getCueAsHTML());
      span2.classList.add('on');
    }

    idx = ++idx % 2;
  }

};

})();
</script>

<p>В этом примере используется метод <code>getCueAsHTML()</code>, возвращающий HTML-версию каждой метки путем преобразования файла из формата WebVTT в объект <code>DocumentFragment</code> HTML на основе <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#webvtt-cue-text-parsing-rules" title="Документация по правилам анализа текста метки WebVTT">анализа</a> текста метки WebVTT и правил <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#webvtt-cue-text-dom-construction-rules" title="Документация по правилам создания текста метки WebVTT в модели DOM">создания модели DOM</a>. С помощью свойства метки <code>text</code> можно извлечь значение ее необработанного текста в том виде, в котором он содержится в файле <code>src</code>.</p>

<p>В этом случае удобно использовать метод <code>getCueAsHTML()</code>, возвращающий HTML-версию каждой метки путем преобразования файла из формата WebVTT в объект <code>DocumentFragment</code> HTML на основе <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#webvtt-cue-text-parsing-rules" title="Документация по правилам анализа текста метки WebVTT">анализа</a> текста метки WebVTT и правил <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#webvtt-cue-text-dom-construction-rules" title="Документация по правилам создания текста метки WebVTT в модели DOM">создания модели DOM</a>. С помощью свойства метки <code>text</code> можно извлечь значение ее необработанного текста в том виде, в котором он содержится в файле <code>src</code>.</p>

<h2 id="toc-markup">Подробнее о разметке</h2>

<p>Разметку можно добавлять в строку метки времени, чтобы указать направление, выравнивание и расположение текста. Текст метки также можно разметить для указания докладчиков (например, имен выступающих) и добавления форматирования. Субтитрами и титрами можно управлять с помощью CSS, как показано ниже.</p>

<pre class="prettyprint">
::cue {
  color: #444;
  font: 1em sans-serif;
}
::cue .warning {
  color: red;
  font: bold;
}
</pre>

<p>На слайдах Сильвии Пфейффер (Silvia Pfeiffer), демонстрирующих <a href="http://html5videoguide.net/presentations/WebVTT/#title-slide" title="Слайды о доступности видео в HTML5">доступность видео в HTML5</a>, приведены и другие примеры работы с разметкой, а также показан процесс создания глав отслеживания для навигации и описаний отслеживания для экранных дикторов.</p>

<h2 id="toc-finally">И наконец…</h2>

<p>Хранение данных меток в текстовых файлах (вместо их внутриполосного кодирования в аудио- или видеофайлах) упрощает создание субтитров и титров, повышает доступность и переносимость данных, а также расширяет возможности поиска.</p>

<p>Элемент отслеживания также позволяет использовать ссылки на хронометрированные метаданные и динамическое содержание при воспроизведении, что делает элементы аудио и видео более эффективными.</p>

<p>Благодаря функциональности, гибкости и простоте использования элемент отслеживания является большим шагом вперед на пути к открытости и динамичности мультимедийного содержания в сети Интернет.</p>

<h2 id="toc-more">Подробнее</h2>

<ul>
  <li>Современный стандарт WHATWG HTML: <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#the-track-element">http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#the-track-element</a></li>
  <li>Рабочий проект W3C HTML5: <a href="http://dev.w3.org/html5/spec/Overview.html#the-track-element" title="Документация по элементу отслеживания рабочего проекта W3C">http://dev.w3.org/html5/spec/Overview.html#the-track-element</a></li>
  <li>Стандарт W3C WebVTT: <a href="http://dev.w3.org/html5/webvtt/#webvtt-cue-timings" title="Стандарт WebVTT">http://dev.w3.org/html5/webvtt/#webvtt-cue-timings</a></li>
  <li>Форматы хронометрированного отслеживания: <a href="http://wiki.whatwg.org/wiki/Timed_track_formats">http://wiki.whatwg.org/wiki/Timed_track_formats</a></li>
  <li>Примеры использования хронометрированного отслеживания: <a href="http://wiki.whatwg.org/wiki/Timed_tracks">http://wiki.whatwg.org/wiki/Timed_tracks</a></li>
  <li><a href="http://www.bbc.co.uk/blogs/researchanddevelopment/2012/01/implementing-startoffsettime-f.shtml" title="Пост в блоге отдела научных исследований и разработок Би-Би-Си">Внеполосные хронометрированные метаданные для потоковой передачи в реальном времени</a>: пост Шона О'Халпина (Sean O'Halpin) в блоге отдела научных исследований и разработок Би-Би-Си.</li>
</ul>

<script>
$(document).ready(function() {
  if (!isCompatible()) {
    var els = document.querySelectorAll('.trackNotSupported');
    for (var i = 0, el; el = els[i]; ++i) {
      el.classList.add('show');
    }
  }
});
</script>
{% endblock %}
